#pragma once

#include "v2d.h"
#include "shape.h"

template<typename VTYPE>
class Circle;

/** standard Line using floats */
#define LineF	Line<float>
#define CircId 1
#define RectId 2
template<typename VTYPE>
class Line:public Shape<VTYPE>
{
protected:
	V2D<VTYPE> a, b;
	int ID;
	int color;
public:
	V2D<VTYPE> getPosition()const{return a;}
	void setPosition(const V2D<VTYPE> & a_position)
	{
		V2D<VTYPE> d = b.difference(a);
		a.set(a_position);
		b.set(a_position.sum(d));
	}
	V2D<VTYPE> getA()const{return a;}
	V2D<VTYPE> getB()const{return b;}
	Line(){}
	void set(const V2D<VTYPE> & a_a, const V2D<VTYPE> & a_b){a=a_a;b=a_b;}
	Line(const V2D<VTYPE> & a_a, const V2D<VTYPE> & a_b){set(a_a,a_b);}
	inline void setColor(const int & a_color)
	{
		color = a_color;
	}
	void glDraw()const
	{
		glColor3ubv((GLubyte*)&color);
		a.glDrawTo(b);}
	bool isClockwise(const V2D<VTYPE> & a_point)
	{
		// use the first point as the anchor point
		V2D<VTYPE> b0 = b.difference(a), p0 = a_point.difference(a);
		return b0.sign(p0) > 0;
	}
	bool collidesWith(const V2D<VTYPE>  mouse) const 
	{
		return (mouse.isWithin(0.5f, a) || mouse.isWithin(0.5f, b));
	}
	void setID(const int anID)
	{
		ID = anID;
	}
	const int getID() const {return ID;}

	V2D<VTYPE> getCenter()const{return a.sum(b).quotient(2);}
	bool shapeCollide(const Shape<VTYPE> * colshape) const
	{
		VTYPE dist;
		V2D<VTYPE> point;
		if(colshape->getID() == CircId) {
			Circle<VTYPE> * c = (Circle<VTYPE> *) colshape;
			V2D<VTYPE> closestPoint;
			return (V2D<VTYPE>::lineCrossesCircle(a, b, c->getPosition(), c->getRadius(), closestPoint));
		}
		if(colshape->getID() == this->getID()) {
			Line<VTYPE> * l = (Line<VTYPE> *) colshape;
			V2D<VTYPE> c = l->getA();
			V2D<VTYPE> d = l->getB();
			return (V2D<VTYPE>::lineIntersection(a, b, c, d, dist, point));
		}
		//if(colshape->getID() == RectId) {
		//	Rect<VTYPE> * r = (Rect<VTYPE> *) colshape;
		//	V2D<VTYPE> p1 = V2D<VTYPE>(r->getMinX(), r->getMinY());
		//	V2D<VTYPE> p2 = V2D<VTYPE>(r->getMaxX(), r->getMinY());
		//	V2D<VTYPE> p3 = V2D<VTYPE>(r->getMaxX(), r->getMaxY());
		//	V2D<VTYPE> p4 = V2D<VTYPE>(r->getMinX(), r->getMaxY());
		//	return (V2D<VTYPE>::lineIntersection(a, b, p1, p2, dist, point) || 
		//			V2D<VTYPE>::lineIntersection(a, b, p2, p3, dist, point) || 
		//			V2D<VTYPE>::lineIntersection(a, b, p3, p4, dist, point) || 
		//			V2D<VTYPE>::lineIntersection(a, b, p4, p1, dist, point)) ||
		//			(r->collidesWith(a) || r->collidesWith(p2));
		//}
	}
};
